package se.webbzon.boltzmann.environment;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;

import se.webbzon.boltzmann.debug.Debug;
import se.webbzon.boltzmann.inflatorgroup.EnvironmentInflatorGroup;
import se.webbzon.boltzmann.player.Player;

public abstract class PlayerEnvironment extends AbstractEnvironment {

	// A collection of all the listeners to this player environment
	private final Collection<PlayerEnvironmentListener> listeners;
	
	// A collection of all the players in the player environment
	private final Collection<Player> players;
	
	// The variable maps of this player environment
	private final VariableMap environmentVariables;

	/*============================================================
	Constructors
	============================================================*/
		
	public PlayerEnvironment(EnvironmentInflatorGroup inflatorGroup) throws Exception {
		super(false,inflatorGroup);
		environmentVariables = new VariableMap();
		listeners = new ArrayList<PlayerEnvironmentListener>();
		players = Collections.synchronizedCollection(new HashSet<Player>());
	}
		
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Adds a listener to this player environment. **/
	public boolean addListener(PlayerEnvironmentListener listener) {
		int d;
		Debug.debugCollection(this, listeners);
		return listeners.add(listener);
	}
	
	/** Removes a listener from this player environment. **/
	public boolean removeListener(PlayerEnvironmentListener listener) {
		return listeners.remove(listener);
	}
	
	/** Clears all listeners in this player environment. **/
	public void clearListeners() {
		listeners.clear();
	}
		
	/** Adds a player to the player environment. **/
	public boolean addPlayer(Player player) {
		if (players.add(player)) {
			int d;
			Debug.debugCollection(this, players);
			for (PlayerEnvironmentListener listener : listeners.toArray(new PlayerEnvironmentListener[0]))
				listener.playerAdded(this, player);
			return true;
		} else
			return false;
	}
		
	/** Removes a player from the player environment. **/
	public boolean removePlayer(Player player) {
		if (players.remove(player)) {
			for (PlayerEnvironmentListener listener : listeners.toArray(new PlayerEnvironmentListener[0]))
				listener.playerRemoved(this, player);
			return true;
		} else
			return false;
	}
		
	/** Clears all the players from the player environment. **/
	public void clearPlayers() {
		for (PlayerEnvironmentListener listener : listeners.toArray(new PlayerEnvironmentListener[0]))
			listener.playersCleared(this);
		players.clear();
	}

	/** Returns a synchronized collection of all the players in the 
	 * player environment. **/
	public Collection<Player> getPlayers() {
		return Collections.unmodifiableCollection(players);
	}
	
	/** Returns the environment variable map of this player environment. **/
	public VariableMap getVariables() {
		return environmentVariables;
	}

}
